#include <nice2d/widgets/stacklayout.h>
#include <nice2d/widgets/controlradioselector.h>

IMPLEMENT_OBJECT(StackLayout,Layout)

class StackLayoutInfo : public LayoutInfo
{
public:
    StackLayoutInfo(HMode inputHMode,VMode inputVMode):
        hmode(inputHMode),
        vmode(inputVMode)
    {
    }

    HMode hmode = HMode_Center;
    VMode vmode = VMode_Center;
    int32_t current = 0;
};

class StackControlSelector : public ControlRadioSelector
{
public:
    void unselected(ControlPointer control) override
    {
        control->hide();
    }
    void selected(ControlPointer control) override
    {
        control->show();
    }
};

class StackLayoutData
{
public:
    std::shared_ptr<StackControlSelector> selector;

    StackLayoutData()
    {
        selector = std::make_shared<StackControlSelector>();
    }
};

StackLayout::StackLayout():
    data(new StackLayoutData())
{
}

StackLayout::~StackLayout()
{
}

void StackLayout::addControl(ControlPointer widget, HMode hmode, VMode vmode)
{
    if(!widget)
        return;

    std::shared_ptr<LayoutInfo> info = std::make_shared<StackLayoutInfo>(hmode,vmode);
    Layout::addWidget(widget,info);

    if(getWidgetCount() == 1)
        data->selector->select(widget);
    else
        widget->setVisible(false);

    data->selector->addControl(widget);
}

void StackLayout::setCurrent(int32_t index)
{
    auto control = getWidgetByIndex(index);
    data->selector->select(control.first);
}

void StackLayout::setCurrent(ControlPointer widget)
{
    if(containsControl(widget))
        data->selector->select(widget);
}

std::weak_ptr<Control> StackLayout::getCurrent()
{
    return data->selector->getSelectedControl();
}

void StackLayout::adjust()
{
    if(getLayoutResizeRule() == LayoutResizeRule_ResizeLayout)
    {
        float maxWidth = 0;
        float maxHeight = 0;
        uint32_t index = 0;
        for(;index<getWidgetCount();index++)
        {
            auto control = getWidgetByIndex(index);
            auto size = control.first->getSize();
            if(control.first->getHResizeRule() == ControlResizeRule_Fixed)
            {
                maxWidth = std::max(maxWidth,size.x);
                maxHeight = std::max(maxHeight,size.y);
            }
        }

        if(maxWidth > 0 && maxHeight > 0)
            setSize(maxWidth+2*getMargin(),maxHeight+2*getMargin());

        for(index=0;index<getWidgetCount();index++)
        {
            auto control = getWidgetByIndex(index);
            if(control.first->getHResizeRule() == ControlResizeRule_Fill)
                control.first->setSize(getSize()-sf::Vector2f(getMargin(),getMargin()));

            auto info = std::dynamic_pointer_cast<StackLayoutInfo>(control.second);
            auto box = control.first->getBoundingBox();
            auto layoutBox = getBoundingBox();

            auto center = Entity::adjustPosition({layoutBox.width,layoutBox.height},sf::Vector2f(box.width,box.height),info->hmode,info->vmode,0,0);
            control.first->setPosition(center);
        }
    }
    else
    {
        uint32_t index = 0;
        for(;index<getWidgetCount();index++)
        {
            auto control = getWidgetByIndex(index);
            if(control.first->getHResizeRule() == ControlResizeRule_Fill)
                control.first->setSize(getSize()-sf::Vector2f(getMargin(),getMargin()));

            auto info = std::dynamic_pointer_cast<StackLayoutInfo>(control.second);
            auto box = control.first->getBoundingBox();
            auto center = Entity::adjustPosition(getBoundingBox(),sf::Vector2f(box.width,box.height),info->hmode,info->vmode,0,0);
            control.first->setCenter(center);
        }
    }
}
